//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
/// @file
///
///
/// 
/// @author Davide Pasca
/// 
//==================================================================

#include "stdafx.h"
#include "rend_device.h"
#include "rend_vertex_buffer.h"

//==================================================================
///
//==================================================================
RendVertexBuffer::RendVertexBuffer( RendDevice *rdevicep, int max_verts, int stride ) :
	_rdevicep(rdevicep),
	_max_verts(0),
	_stride(0),
	_total_alloc_size(0)
#ifdef TARGET_D3D
	,
	_d3d_last_idx(0)
#endif
{
	// $$$ DAVIDE - ummm - PASSERT( _rdevicep->IsRendering() == false );
	ReallocBuffer( max_verts, stride );
}

//==================================================================
#ifdef _DEBUG
RendVertexBuffer::~RendVertexBuffer()
{
	// $$$ DAVIDE - ummm - PASSERT( _rdevicep->IsRendering() == false );
}
#endif

//==================================================================
void RendVertexBuffer::ReallocBuffer( int max_verts, int stride )
{
	// these are updated every time anyway (upload needs to know the actual number)
	_max_verts = max_verts;
	_stride = stride;

	// if the buffer is smaller, there is no need to allocate a new one !
	if ( max_verts * stride <= _total_alloc_size )
		return;

	_total_alloc_size = (_max_verts+1) * _stride;

#ifdef TARGET_D3D
	D3DDevice	*d3ddevp = _rdevicep->GetD3DDevice();

	// release the current one
	if ( _d3d_vbuffp )
	{
		_d3d_vbuffp->Release();
		_d3d_vbuffp = NULL;
	}

	HRESULT	hr;
	hr = d3ddevp->CreateVertexBuffer(	_total_alloc_size, D3DUSAGE_WRITEONLY, 0L,
										D3DPOOL_DEFAULT, &_d3d_vbuffp, NULL );

	if ERR_ERROR( hr )
	{
		_total_alloc_size = 0;
		throw "CreateVertexBuffer failed !";
	}
#endif
}

//==================================================================
void RendVertexBuffer::UploadData( const u_char *src_datap, int from_vert, int n_verts )
{
	if ( n_verts <= 0 )
		return;

	u_int	tot_use_size = n_verts * _stride;

	if NOT( tot_use_size )
		return;

#ifdef TARGET_D3D
	void	*destp;
	_d3d_vbuffp->Lock( from_vert * _stride, tot_use_size, (VOID**)&destp, NULL );
	memcpy( destp, src_datap, tot_use_size );
	_d3d_vbuffp->Unlock();

#endif
}
